from Settings import Settings
from pimWriter import pimWriter
from svnClient import svnClient
from sqliteDB import sqliteDB
import os
import time
import commands
##@author Alessio Di Pietro
#@author Irene Scionti
#@brief restore an entry
class pimRestorer(object):
    '''
    Manage entry restore process into evolution's pim files
    '''

    ##@param settings settings object
    def __init__(self,settings):
        '''
        Constructor
        '''
        self.__pimwriter=pimWriter(settings)
        self.__settings=settings
        self.__pimwriter=pimWriter(settings)
        self.__svn_workingcopy=settings.svnWorkingCopy;
        self.__tmp_workingcopy=settings.tmpworkingcopy;
        self.__entry_paths=[settings.contacts_diffname,settings.calendar_diffname,settings.memos_diffname];
        '''
        self.__entry_paths(0) --> contacts
        self.__entry_paths(1) --> calendar
        self.__entry_paths(2) --> memos
        
        '''

        #database parameters
        self.__fts_db_name=settings.fts_db;
        self.__fts_db=sqliteDB(self.__svn_workingcopy+'/index/'+self.__fts_db_name)
        self.__fts_table_names=["contacts_index","calendar_index","memos_index"]
        self.__modified_db_table_names=["modified_contacts","modified_calendar","modified_memos"]
        self.__removed_db_table_names=["removed_contacts","removed_calendar","removed_memos"]
        
        self.__tmp_svnclients=[]
        self.__svnclients=[]
        for dir in self.__entry_paths:
            #initialize a list that contains one svn client object for each entry type
            self.__tmp_svnclients.append(svnClient(self.__tmp_workingcopy+dir,settings.svnServer,settings.svnRepoName,settings.svnUser,settings.svnPassword))
            self.__svnclients.append(svnClient(self.__svn_workingcopy+dir,settings.svnServer,settings.svnRepoName,settings.svnUser,settings.svnPassword))
        
        self.__entry_svnclient=svnClient(self.__svn_workingcopy,settings.svnServer,settings.svnRepoName,settings.svnUser,settings.svnPassword)
    
    ##@brief wrapper method for pimwriters
    # @param entry_type entry type
    # @param file_path path of evolution's pim file
    # @param file_name name of evolution's pim file
    def writers(self,entry_type,file_path,file_name):
        if entry_type==0:#contacts
            self.__pimwriter.berkleyWrite(file_path, file_name)
        if entry_type==1:#calendar
            self.__pimwriter.icsWrite(file_path, file_name)
        if entry_type==2:#memos
            self.__pimwriter.memosWrite(file_path, file_name)
    ## @brief wrapper method for pimremovers
    # @param entry_type entry type
    # @param entry_uid entry uid  
    def removers(self,entry_type,entry_uid):
        if entry_type==0:#contacts
            self.__pimwriter.contactsRemove(entry_uid)
        if entry_type==1:#calendar
            self.__pimwriter.icsRemove(entry_uid)
        if entry_type==2:#memos
            self.__pimwriter.memosRemove(entry_uid)
    
    ## @brief restore an entry
    # @param entry_uid entry
    # @param entry_revision revision to restore
    # @param entry_type entry type
    # @return any exception (string)
    def restore(self,entry_uid,entry_revision,entry_type):
        '''
        Restore a single entry using it's uid and desired svn revision
        '''
        errors="noerrors";
        try:
            c=self.__fts_db.open()
            #reset temp workingcopy
            os.system("rm -rf "+self.__tmp_workingcopy+" 2> /dev/null")
            os.mkdir(self.__tmp_workingcopy)
       
            #checkout all entries at revision entry_revision in tmp_workingcopy
            self.__tmp_svnclients[entry_type].setURL(self.__settings.svnServer+self.__entry_paths[entry_type]+"/"+entry_uid)
            self.__tmp_svnclients[entry_type].checkout(entry_revision)
            
            #path to restored entry file
            restored_entry_file=self.__tmp_workingcopy+self.__entry_paths[entry_type]+"/"+entry_uid
            #path to working copy entry file
            workingcopy_entry_dir=self.__svn_workingcopy+self.__entry_paths[entry_type]+"/"+entry_uid;
            os.system("svn cleanup "+self.__svn_workingcopy)
            #check if entry exists in svn workingcopy (edited entry)    
            if os.path.exists(workingcopy_entry_dir):
                #remove actual entry from working copy
                self.__svnclients[entry_type].revert("/"+entry_uid);
                self.__svnclients[entry_type].update('head');
                self.__svnclients[entry_type].remove("/"+entry_uid+"/"+entry_uid)
                self.__svnclients[entry_type].remove("/"+entry_uid)
                self.__entry_svnclient.commit("Pim committed at "+time.asctime( time.localtime(time.time())))
                #remove entry from evolution db
                self.removers(entry_type, entry_uid)
        
            
            
            #set as new entry
            #delete from modified db table
            c.execute("DELETE FROM "+self.__modified_db_table_names[entry_type]+" WHERE uid=? ",(entry_uid,))
            #remove entry from removed db table
            c.execute("DELETE FROM "+ self.__removed_db_table_names[entry_type] + " WHERE uid=? ",(entry_uid,));
            self.__fts_db.commit();
            '''
            #select entry state from db
            c.execute("SELECT state FROM "+self.__fts_table_names[entry_type]+" WHERE uid=? AND rev=?",(entry_uid,str(entry_revision),))
            row=c.fetchone()
            if row!=None:
                state=row[0]
                if state=='d':
                    #update entry in index db table as modified entry
                    c.execute("UPDATE "+self.__fts_table_names[entry_type]+" SET state='m',removed_timestamp='null' WHERE uid=?",(entry_uid,))
            '''
            c.execute("DELETE FROM "+self.__fts_table_names[entry_type]+" WHERE uid=? AND rev=?",(entry_uid,int(entry_revision),))
            self.__fts_db.commit();
            self.__fts_db.close();
            
            #write the entry into evolution's pim file
            self.writers(entry_type,self.__tmp_workingcopy+self.__entry_paths[entry_type]+"/",entry_uid)
           
            #restart evolution backend
            os.system("evolution --force-shutdown --display=:0")
        except Exception, e:
            errors=e;
        finally:
            return errors
            
        
        
        
        
        